﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
using System.IO;
using System.Globalization;
using debugger;
using SDcard;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Net.Sockets;
using System.Net;
using System.Diagnostics;

namespace WindowsFormsApplication1
{

    public sealed partial class Form1 : Base
    {
        public static uint CACHE_CTL = 0x42000000;

        public const byte HALT_DEBUG = 0x10;
        public const byte FORCE_HALT = 0x11;
        public const byte DEBUG_RESET_N0 = 0x12;
        public const byte DEBUG_RESET_N1 = 0x13;
        public const byte DEBUG_STEP = 0x14;
        public const byte SET_DEBUG_RW_CMD = 0x15;//{debug_mem_dummy,debug_rw_cmd} <= data[3:0];
        public const byte SET_DEBUG_ADDRESS = 0x16;
        public const byte SET_DEBUG_WRITEDATA = 0x17;
        public const byte SET_DEBUG_VGA_BASE_ADDR = 0x18;
        public const byte SET_DEBUG_FLG = 0x19;
        public const byte SET_DEBUG_HID = 0x1A;
        public const byte SET_DEBUG_HID_REQ = 0x1B;
        public const byte GET_ECHO = 0x1C;
        public const byte GET_CONST_ECHO = 0x1D;

        public const byte GET_DEBUG8 = 0x20;
        public const byte GET_DEBUG32 = 0x21;
        public const byte GET_ACCESS_TIME = 0x22;
        public const byte GET_AVM_M0_ADDRESS = 0x23;
        public const byte GET_PRIVATE_OFFSET_REAR = 0x24;

        public const byte GET_PC_RECORD_DATA = 0x25;
        public const byte GET_PC_RECORD_INDEX = 0x26;
        public const byte GET_MISC = 0x27;
        //public const byte GET_IRQ_ADDR = 0x28;
        public const byte GET_IRQ_ID = 0x28;
        public const byte GET_CPU_ADDRESS = 0x29;
        public const byte GET_PC = 0x2A;
        public const byte GET_PRIVATE_OFFSET = 0x2B;
        //public const byte GET_PC_RESULT = 0x2C;
        public const byte GET_CURR_DATA = 0x2D;
        public const byte GET_DEBUG_STASH_DATA = 0x2E;
        public const byte GET_DEBUG_STASH_INDEX = 0x2F;

        public const byte MEM_READ = 0x30;
        public const byte MEM_WRITE = 0x31;
        public const byte INS_READ = 0x32;
        public const byte MEM_TRANS_READ = 0x34;
        public const byte MEM_TRANS_WRITE = 0x35;
        public const byte REG_READ = 0x37;
        public const byte TRANS_READ = 0x38;
        public const byte TRANS_WRITE = 0x39;


        public const byte DEBUG_TX_TO_PC = 0x40;
        public const byte DEBUG_TX_STATUS_TO_PC = 0x41;
        public const byte DEBUG_RX_FROM_PC = 0x42;
  

        public const byte VGA_CONTROL_BY_DEBUGGER = 0x50;
        public const byte VGA_DEBUGGER_READ_LINE_ADDR = 0x51;
        public const byte VGA_DEBUGGER_READ_LINE_REQ = 0x52;


        public const byte SET_CACHE_DEBUG_INDEX = 0x60;
        public const byte GET_CACHE_DEBUG_DATA = 0x61;
        public const byte GET_INS_CACHE_DEBUG_DATA = 0x66;
        public const byte GET_FLUSH_COUNT = 0x65;
        public const byte GET_GLICH_COUNT = 0x68;
        public const byte GET_GLICH_COUNT_INS = 0x69;

        public const byte GET_CACHE_CONFIG = 0x67;
        public const byte NOCACHE0 = 0x62;
        public const byte NOCACHE1 = 0x63;
        public const byte GET_CACHE_LIFE_COUNT = 0x64;


        public const byte SPIROM_DEBUG_CS0 = 0x70;
        public const byte SPIROM_DEBUG_CS1 = 0x71;
        public const byte SPIROM_REC = 0x72;
        public const byte SPIROM_SND = 0x73;
        public const byte SPIROM_SND4 = 0x74;
        public const byte SPIROM_TRANS_WRITE = 0x76;


        public Form1()
        {
            InitializeComponent();

            this.FormClosed += new FormClosedEventHandler(Form1_FormClosed);

            this.trackBar1.MouseUp += trackBar1_MouseUp;
            this.trackBar1.MouseDown += trackBar1_MouseDown;

        }

        void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
        }
        string portName;

        private void Form1_Load(object sender, EventArgs e)
        {
            bool ret = connect();
            if (!ret)
            {
                foreach (var item in this.Controls)
                {
                    (item as Control).Enabled = false;
                }
                this.button10.Enabled = true;
                this.textBox3.Enabled = true;
                this.button15.Enabled = true;
                this.textBox4.Enabled = true;
                this.button7.Enabled = true;
            }
            else
            {
                loadSym();
            }
            this.comboBox2.SelectedIndex = 0;
            this.comboBox1.SelectedIndex = 0;
            loadalldata();

            this.textBox7.Text = ""+(62*1024);//63488;
        }



        List<CodeSym> syms;


        private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                getstatus();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        public void getCacheDebugData(int id, StringBuilder sb, out uint addr, out uint life, out string invalid, out string dirty, bool isIns = false)
        {
            sendCmd(SET_CACHE_DEBUG_INDEX, (uint)id);
            uint val;
            if (isIns)
            {
                val = sendCmdRet(GET_INS_CACHE_DEBUG_DATA);
            }
            else
            {
                val = sendCmdRet(GET_CACHE_DEBUG_DATA);
            }
            //                     16                             1                                15
            //cache_debug_data <= {cache_life[cache_debug_index], cacheInvalid[cache_debug_index], cacheAddrHigh[cache_debug_index]};

            if ((val & 0x80000000) != 0)
            {
                dirty = " D";
            }
            else
            {
                dirty = "  ";
            }
            if ((val & 0x40000000) != 0)
            {
                invalid = "  ";
            }
            else
            {
                invalid = " V";
            }
            addr = (val & 0x0000ffff) << 10;
            if (sb != null)
            {
                sb.Append(dirty + invalid + Util.getHex8((uint)addr));
            }

            life = (val >> 16) & 0x00003fff;
            if (sb != null)
            {
                sb.Append(String.Format(",{0: 00}", life));
            }

        }


        public uint getAccessTime()
        {
            if (!isBasic)
            {
                return sendCmdRet(GET_ACCESS_TIME);
            }
            else
            {
                return 0;
            }
        }


        public void getstatus()
        {
            uint temp;
            clearBuff();

            int baseaddr = 0;

            //temp = sendCmdRet(GET_CONST_ECHO);
            //if (temp != 0x12345678)
            //{
            //    throw new Exception("checkerror");
            //}

            //temp = sendCmdRet(GET_ECHO, 123);
            //if (temp != 123)
            //{
            //    throw new Exception("checkerror");
            //}

            //sendCmd(SET_TRANSFER_BASE_ADDR, 0);

            StringBuilder sb = new StringBuilder();

            int pc;

            try
            {
                pc = Convert.ToInt32(textBox6.Text, 16);
            }
            catch
            {
                sb.Append("pc:");
                pc = (int)sendCmdRet(GET_PC);
                sb.Append(Util.getHex8(pc));
            }

            sb.Append("  private_offset:");
            temp = sendCmdRet(GET_PRIVATE_OFFSET);
            sb.Append(Util.getHex8(temp));

            sb.Append("  private_offset_rear:");
            temp = sendCmdRet(GET_PRIVATE_OFFSET_REAR);
            sb.Append(Util.getHex8(temp));

            sb.Append("  avm_m0_address:");
            temp = sendCmdRet(GET_AVM_M0_ADDRESS);
            sb.Append(Util.getHex8(temp));

            //sb.Append("  pcResult:");
            //temp = sendCmdRet(GET_PC_RESULT);
            //sb.Append(Util.getHex8(temp));

            //sb.Append("  last RtypeCmd:");
            //portWrite((byte)(0x18), (byte)0x00); temp = readFromPort(1); sb.Append(Util.getHex2(temp[0]));

            //4        3         2                  1          0
            //halt_cpu,halt_uart,avm_m0_waitrequest,irq_enable,irq_req
            temp = sendCmdRet(GET_MISC);

            uint halt_cpu = (temp >> 4) & 1;
            sb.Append("  halt_cpu:");
            sb.Append(halt_cpu);

            uint halt_uart = (temp >> 3) & 1;
            sb.Append("  halt_uart:");
            sb.Append(halt_uart);

            sb.Append("  waitRequest:");
            sb.Append((temp >> 2) & 1);

            sb.Append("  waitRequestIns:");
            sb.Append((temp >> 5) & 1);

            sb.Append("  irq_enable:");
            sb.Append((temp >> 1) & 1);

            sb.Append("  irq_req:");
            sb.Append((temp >> 0) & 1);

            sb.Append("  irq_id:");
            temp = sendCmdRet(GET_IRQ_ID);
            sb.Append(temp);

            sb.Append("  cpu_address:");
            temp = sendCmdRet(GET_CPU_ADDRESS);
            sb.Append(Util.getHex8(temp));


            sb.Append("  curr_data:");
            temp = sendCmdRet(GET_CURR_DATA);
            sb.Append(Util.getHex8(temp));

            //if (!isBasic)
            //{
            //    sb.Append("  debugin:");
            //    temp = sendCmdRet(GET_DEBUG8);
            //    sb.Append(Util.getBin8(temp));
            //    sb.Append("  debugin32:");
            //    temp = sendCmdRet(GET_DEBUG32);
            //    sb.Append(Util.getHex8(temp));
            //}
            //sb.AppendLine();

            sb.Append("  access time:");
            sb.Append(getAccessTime());
            sb.AppendLine();

            if (!isBasic)
            {
                sb.Append("  pc_record_Index:");
                uint index = sendCmdRet(GET_PC_RECORD_INDEX);
                sb.Append(index);
                sb.AppendLine();
                int cnt = Convert.ToInt32(this.comboBox2.Text);
                for (int i = 0; i < cnt; i++)
                {
                    sb.Append("  pc_record:" + (byte)(index + i - cnt) + ",");
                    sendCmd(SET_DEBUG_ADDRESS, (uint)(index + i - cnt));
                    temp = sendCmdRet(GET_PC_RECORD_DATA);
                    sb.Append(Util.getHex8(temp));
                    sb.AppendLine();
                }
                sb.AppendLine();
            }

            if (!isBasic)
            {
                sb.Append("  debug_stash_Index:");
                uint index = sendCmdRet(GET_DEBUG_STASH_INDEX);
                sb.Append(index);
                sb.AppendLine();
                int cnt = Convert.ToInt32(this.comboBox2.Text);
                for (int i = 0; i < cnt; i++)
                {
                    sb.Append("  debug_stash:" + (byte)(index + i - cnt) + ",");
                    sendCmd(SET_DEBUG_ADDRESS, (uint)(index + i - cnt));
                    temp = sendCmdRet(GET_DEBUG_STASH_DATA);
                    sb.Append(Util.getHex8(temp));
                    sb.AppendLine();
                }
                sb.AppendLine();
            }

            if (!isBasic)
            {
                sb.Append("cache:");
                temp = sendCmdRet(GET_CACHE_LIFE_COUNT);
                sb.Append(Util.getHex8(temp));
                sb.Append(" flush count:");
                temp = sendCmdRet(GET_FLUSH_COUNT);
                sb.Append(Util.getHex8(temp));

                sb.Append(" glich count:");
                temp = sendCmdRet(GET_GLICH_COUNT);
                sb.Append(Util.getHex8(temp));
                if (temp > 0) { this.Text = "glich"; }

                sb.Append(" glich count ins:");
                temp = sendCmdRet(GET_GLICH_COUNT_INS);
                sb.Append(Util.getHex8(temp));
                if (temp > 0) { this.Text = "glichIns"; }

                sb.AppendLine();
            }
            if (!isBasic)
            {
                temp = sendCmdRet(GET_CACHE_CONFIG);
                int cache_count = (int)(temp & 0xFF);
                int group_count = (int)((temp >> 8) & 0xFF);

                int cache_count_ins = (int)((temp >> 16) & 0xFF);
                int group_count_ins = (int)((temp >> 24) & 0xFF);


                for (int j = 0; j < group_count; j++)
                {
                    sb.Append("Group:" + j + " ");

                    //sendCmd(SET_DEBUG_RW_CMD, 8);//debug_mem_dummy
                    //sendCmd(SET_DEBUG_ADDRESS, addr);
                    //sendCmdRet(MEM_READ);

                    for (int i = 0; i < cache_count; i++)
                    {
                        //sb.Append(String.Format("{0:00}", i) + ":[");
                        sb.Append(" [");
                        uint life;
                        uint addr;
                        string invalid;
                        string dirty;
                        getCacheDebugData(i * group_count + j, sb, out life, out addr, out invalid, out dirty);
                        sb.Append("] ");
                        //if ((i & 7) == 7) sb.AppendLine();
                    }
                    sb.AppendLine();
                }

                for (int j = 0; j < group_count_ins; j++)
                {
                    sb.Append("GroupIns:" + j + " ");
                    for (int i = 0; i < cache_count_ins; i++)
                    {
                        //sb.Append(String.Format("{0:00}", i) + ":[");
                        sb.Append(" [");
                        uint life;
                        uint addr;
                        string invalid;
                        string dirty;
                        getCacheDebugData(i * group_count_ins + j, sb, out life, out addr, out invalid, out dirty, true);
                        sb.Append("] ");
                        //if ((i & 7) == 7) sb.AppendLine();
                    }
                    sb.AppendLine();
                }

            //sb.Append("  numer:"); getreg(0x40, 0, sb);
            //sb.Append("  denom:"); getreg(0x41, 0, sb);
            //sb.Append("  quotient:"); getreg(0x42, 0, sb);
            //sb.Append("  remain:"); getreg(0x45, 0, sb);


            sb.AppendLine();
            }

            if (!isBasic && (halt_cpu != 0 || halt_uart != 0))
            {
                int sp = 0;
                getRegArray();
                sb.Append("r0:");
                getReg(0x00, sb);
                sb.Append(" r1:");
                getReg(0x01, sb);

                sb.Append("   r2:");
                getReg(0x02, sb);
                sb.Append(" r3:");
                getReg(0x03, sb);
                sb.AppendLine();

                for (int i = 4; i < 8; i++)
                {
                    sb.Append(" r" + i + ":");
                    getReg((byte)i, sb);
                }
                sb.AppendLine();

                for (int i = 8; i < 16; i++)
                {
                    sb.Append(" r" + i + ":");
                    getReg((byte)i, sb);
                }
                sb.AppendLine();

                for (int i = 16; i < 24; i++)
                {
                    sb.Append(" r" + i + ":");
                    getReg((byte)i, sb);
                }
                sb.AppendLine();

                sb.Append("sp:");
                sp = (int)getReg(27, sb);

                sb.Append("    fp:");
                getReg(28, sb);
                sb.AppendLine();

                sb.Append(" re:");
                getReg(29, sb);

                sb.Append(" ra:");
                getReg(31, sb);
                sb.AppendLine();

                for (int i = 32; i < 64; i++)
                {
                    sb.Append(" i" + (i-32) + ":");
                    getReg((byte)i, sb);
                }
                sb.AppendLine();

                sb.AppendLine("stack: ");
                baseaddr = sp;
                for (int i = -Convert.ToInt32(this.comboBox2.Text) * 4; i < Convert.ToInt32(this.comboBox2.Text) * 4; i += 4)
                {
                    sb.Append((i == 0 ? "*" : " ") + Util.getHex8((uint)(i + baseaddr)) + ":"); getmem((uint)(baseaddr + i), sb); sb.AppendLine();
                }

                baseaddr = 0;
                sb.AppendLine("code: ");
                for (int i = -Convert.ToInt32(this.comboBox2.Text) * 4; i < Convert.ToInt32(this.comboBox2.Text) * 4; i += 4)
                {
                    StringBuilder sb2 = new StringBuilder();
                    uint code = getmem((uint)(pc + i), sb2, true);
                    int target = pc + i;
                    string foundsym = Config.getSym(target, syms);
                    string scode = Config.dasm(syms, cfgs, (uint)code, pc + i, baseaddr);
                    if (i == 0)
                    {
                        sb.AppendLine("----------------------------------------------------------------------------------");
                    }
                    sb.AppendLine((i == 0 ? "*" : " ") + Util.getHex8((uint)(pc + i)) + ":" + scode);
                    if (i == 0)
                    {
                        sb.AppendLine("----------------------------------------------------------------------------------");
                    }
                }

                sb.AppendLine("mem: ");
                baseaddr = Convert.ToInt32(textBox1.Text, 16);
                for (int i = 0; i < Convert.ToInt32(this.comboBox2.Text) * 4 * 2; i += 4)
                {
                    sb.Append("" + Util.getHex8((uint)(baseaddr + i)) + ":"); getmem((uint)(baseaddr + i), sb); sb.AppendLine();
                }
            }

            this.textBox4.Text = sb.ToString();
        }

        private void textBox4_TextChanged(object sender, EventArgs e)
        {

        }

        //public int getData(int baseCmd, StringBuilder sb)
        //{
        //	byte[] temp;
        //	int val = 0;
        //	portWrite((byte)(baseCmd + 0x3), (byte)0x00); temp = readFromPort(1); val |= temp[0] << 24; if (sb != null) sb.Append(Util.getHex2(temp[0]));
        //	portWrite((byte)(baseCmd + 0x2), (byte)0x00); temp = readFromPort(1); val |= temp[0] << 16; if (sb != null) sb.Append(Util.getHex2(temp[0]));
        //	portWrite((byte)(baseCmd + 0x1), (byte)0x00); temp = readFromPort(1); val |= temp[0] << 8; if (sb != null) sb.Append(Util.getHex2(temp[0]));
        //	portWrite((byte)(baseCmd + 0x0), (byte)0x00); temp = readFromPort(1); val |= temp[0] << 0; if (sb != null) sb.Append(Util.getHex2(temp[0]));
        //	return val;
        //}

        public uint getmem(uint addr, StringBuilder sb, bool isIns = false)
        {
            sendCmd(SET_DEBUG_RW_CMD, 0);//ldw
            
            sendCmd(SET_DEBUG_ADDRESS, addr);
            uint val;
            if (isIns)
            {
                val = sendCmdRet(INS_READ);
            }
            else
            {
                val = sendCmdRet(MEM_READ);
            }
            if (sb != null)
            {
                sb.Append(Util.getHex8(val));
            }
            return val;
        }

        public bool setmem(uint addr, uint data, bool noerr = false, bool no31 = false)
        {
            int byteEnable = comboBox1.SelectedIndex;
            uint debug_rw_cmd = 1;
            switch (byteEnable)
            { //0: DW  1:word 2: byte
                case 0: debug_rw_cmd = 1; break;//3'b001;//stw
                case 1: debug_rw_cmd = 7; break;//3'b111;//sth
                case 2: debug_rw_cmd = 6; break;//3'b110;//stb
            }
            sendCmd(SET_DEBUG_RW_CMD, debug_rw_cmd);

            sendCmd(SET_DEBUG_ADDRESS, addr);
            sendCmd(SET_DEBUG_WRITEDATA, data);

            if (!no31)
            {
                uint temp = sendCmdRet(MEM_WRITE);
                if (temp != 123)
                {
                    if (!noerr)
                    {
                        throw new Exception("err");
                    }
                    else
                    {
                        return false;
                    }
                }
            }
            return true;
        }

        private void button2_Click_1(object sender, EventArgs e)
        {

            clearBuff();

            uint addr = Convert.ToUInt32(textBox1.Text, 16);

            //NoCache(addr, checkBox8.Checked);

            StringBuilder sb = new StringBuilder();
            if (checkBox9.Checked)
            {
                uint val = getReg(addr);
                sb.Append(Util.getHex8(val));
            }
            else
            {
                getmem(addr, sb, checkBox2.Checked);
            }

            textBox2.Text = sb.ToString();
            //getstatus();

            uint inc = Convert.ToUInt32(textBox5.Text, 16);
            addr += inc;
            textBox1.Text = Util.getHex8(addr);

        }

        private void button15_Click(object sender, EventArgs e)
        {
            uint addr = Convert.ToUInt32(textBox1.Text, 16);
            this.FlushCache(addr);
        }

        private void button6_Click(object sender, EventArgs e)
        {
            clearBuff();


            uint addr = Convert.ToUInt32(textBox1.Text, 16);
            uint val = Convert.ToUInt32(textBox2.Text, 16);
            //if (checkBox9.Checked)
            //{
            //    setReg(addr, val);
            //}
            //else
            //{
                setmem(addr, val, false, false);
            //}

            uint inc = Convert.ToUInt32(textBox5.Text, 16);
            addr += inc;
            textBox1.Text = Util.getHex8(addr);

            //getstatus();
        }


        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox1.Checked)
            {
                sendCmd(HALT_DEBUG, 1);
                sendCmd(FORCE_HALT, 1);
            }
            else
            {
                sendCmd(FORCE_HALT, 0);
                sendCmd(HALT_DEBUG, 0);
            }

        }

        private void button3_Click_1(object sender, EventArgs e)
        {
            sendCmd(DEBUG_STEP);
            getstatus();
        }

        public void clearBuff()
        {
            //connect();
        }
        private void button5_Click(object sender, EventArgs e)
        {
            this.connect();
        }

        private void makeImg()
        {
            String[] files = Directory.GetFiles(@"E:\fpgaproj\mine.new\", "*.bmp");

            foreach (var item in files)
            {
                Bitmap b = new Bitmap(item);

                FileStream fs = new FileStream(item.Replace(".bmp", ".img"), FileMode.CreateNew, FileAccess.Write);
                for (int j = 0; j < b.Height; j++)
                {
                    for (int i = 0; i < b.Width; i++)
                    {
                        uint val = getpixel(b.GetPixel(i, j));
                        fs.WriteByte((byte)val);
                        fs.WriteByte((byte)(val >> 8));
                    }
                }
                fs.Close();
            }
        }

        public static uint getpixel(Color c)
        {
            uint val = 0;
            val += ((uint)(c.R) >> 3) << (5 + 6);
            val += ((uint)(c.G) >> 2) << (5);
            val += ((uint)(c.B) >> 3);
            return val;
        }
        public static Color setpixel(int v)
        {
            int r = ((v >> 11) & 0x1F) << 3;
            int g = ((v >> 5) & 0x3F)<<2;
            int b = (v & 0x1F)<<3;
            return Color.FromArgb(r,g,b);
        }

        uint[] data;

        public uint FlushCache(uint addr)
        {
            setmem(CACHE_CTL, 0x80000000 | (addr >> 10));
            getmem(addr, null);
            uint time = this.getAccessTime();
            setmem(CACHE_CTL, 0);
            return time;
        }

        bool stop = false;

        private void button7_Click(object sender, EventArgs e)
        {

            //uint ret = sendCmdRet(DEBUG_RX_FROM_PC, 0x123);
            //uint ret = sendCmdRet(DEBUG_TX_STATUS_TO_PC);
            //if (ret!=0) {
            //    uint val = sendCmdRet(DEBUG_TX_TO_PC);
            //    textBox4.Text = Util.getHex8(val);
            //}
            //
            //return;
      // public const byte  DEBUG_TX_TO_PC= 0x40;
         // public const byte   DEBUG_TX_STATUS_TO_PC= 0x41;
        //public const byte     DEBUG_RX_FROM_PC= 0x42 ;
  
            /*
            return;

            uint val0;
            uint val1;
            uint val2;
            uint val3;
            uint val4;
            uint val5;
            uint val6;
            uint val7;


            sendCmd(0x5B, 1);

            sendCmd(0x58, 2);
            sendCmd(0x59, 0x22222222);
            ret = sendCmdRet(0x5D, null);

            sendCmd(0x58, 0);
            sendCmd(0x59, 0x12345678);
            ret = sendCmdRet(0x5D, null);

            sendCmd(0x58, 1);
            sendCmd(0x59, 0x11111111);
            ret = sendCmdRet(0x5D, null);


            sendCmd(0x5B, 0);


            ret = sendCmdRet(0x5C, null);

            val0 = sendCmdRet(0x50, null);
            val1 = sendCmdRet(0x51, null);
            val2 = sendCmdRet(0x52, null);
            val3 = sendCmdRet(0x53, null);
            val4 = sendCmdRet(0x54, null);
            val5 = sendCmdRet(0x55, null);
            val6 = sendCmdRet(0x56, null);
            val7 = sendCmdRet(0x57, null);

            this.textBox4.Text = val0.ToString() + "," + val2.ToString() + "," + val3.ToString();
            return;
            
            debugport test 
            int ok = 0;
            int ng = 0;
            int ex = 0;
            Random r = new Random();
            byte[] buff = new byte[1024];
            r.NextBytes(buff);
            while (true)
            {
                for (int i = 0; i < 1024; i++)
                {
                    try
                    {
                        portWriteNew((byte)(0x08), buff[i]);
                        uint temp = readFromPort();
                        if (temp != buff[i])
                        {
                            ng++;
                        }
                        else
                        {
                            ok++;
                        }
                    }
                    catch (Exception exc) { 
                        ex++;
                    }
                }
                this.Text = "ok:" + ok + " ng" + ng + " ex:" + ex;
                Application.DoEvents();
                if (stop) {
                    break;
                }
            }
            return;*/


            Form2 form2 = new Form2();
            form2.mainForm = this;
            form2.Show();
        }

        List<Config> cfgs;

        private void loadSym()
        {
            cfgs = Config.loadConfig(@"assembler\config.txt");

            syms = new List<CodeSym>();
            FileStream fs = new FileStream("temp.sym", FileMode.Open, FileAccess.Read);
            StreamReader sw = new StreamReader(fs);
            string s = sw.ReadToEnd();
            sw.Close();
            fs.Close();
            foreach (var line in s.Split('\n'))
            {
                if (line != "")
                {
                    CodeSym sym = new CodeSym();
                    sym.pos = int.Parse(line.Split(',')[0]);
                    sym.name = line.Split(',')[1];
                    syms.Add(sym);
                }
            }
        }


        private void button8_Click(object sender, EventArgs e)
        {

        }

        private void button9_Click(object sender, EventArgs e)
        {
            clearBuff();

            sendCmd(DEBUG_RESET_N0);//debug_reset_n<=1'b0

            Thread.Sleep(100);

            sendCmd(DEBUG_RESET_N1);

        }

        private void button10_Click(object sender, EventArgs e)
        {
            string src = textBox4.Text;
            textBox4.Text = hid(src);
        }

        static string hid(string src)
        {
            string[] arr = src.Split(',');
            int idx = 0;
            int indent = 0;
            int globalUserPage = 0;
            int localUserPage = 0;

            StringBuilder sb = new StringBuilder();
            while (true)
            {
                if (idx >= arr.Length) break;
                string item = arr[idx++];
                int val = Convert.ToInt32(item, 16);
                int len = val & 3;
                if (len == 3) len = 4;
                int type = (val >> 2) & 3;
                int tag = (val >> 4) & 0x0F;
                string stype = "";
                string stag = "";
                string data = "";
                int data0 = 0;

                if (idx < arr.Length)
                {
                    data0 = Convert.ToInt32(arr[idx], 16);
                }
                if (type == 0)
                {
                    stype = "Main";
                    if (tag == 8)
                    {
                        stag = "Input";
                        //Bit 0    {Data (0) | Constant (1)}
                        //Bit 1    {Array (0) | Variable (1)}
                        //Bit 2    {Absolute (0) | Relative (1)}
                        //Bit 3    {No Wrap (0) | Wrap (1)}
                        //Bit 4    {Linear (0) | Non Linear (1)}
                        //Bit 5    {Preferred State (0) | No Preferred (1)}
                        //Bit 6    {No Null position (0) | Nullstate(1)}
                        //Bit 7    Reserved (0)
                        //Bit 8    {Bit Field (0) | Buffered Bytes (1)}
                        //Bit 31-9 Reserved (0)
                        data = Util.getBin8(data0);
                    }
                    else if (tag == 9)
                    {
                        stag = "Output";
                    }
                    else if (tag == 10)
                    {
                        stag = "Collection";
                        //Collection 1010 00 nn 
                        //0x00       Physical (group of axes)
                        if (data0 == 0)
                        {
                            data = "Physical (group of axes)";
                        }
                        //0x01       Application (mouse, keyboard) 
                        if (data0 == 1)
                        {
                            data = "Application (mouse, keyboard) ";
                        }
                        //0x02       Logical (interrelated data) 
                        //0x03       Report 
                        //0x04       Named Array 
                        //0x05       Usage Switch 
                        //0x06       Usage Modifier 
                        //0x07-0x7F  Reserved  
                        //0x80-0xFF  Vendor-defined
                    }
                    else if (tag == 11)
                    {
                        stag = "Feature";
                    }
                    else if (tag == 12)
                    {
                        stag = "End Collection";
                        indent--;
                    }
                    else
                    {
                        stag = "?";
                    }

                }
                else if (type == 1)
                {
                    stype = "Global";
                    if (tag == 0)
                    {
                        stag = "Usage Page";
                        globalUserPage = data0;
                        if (data0 == 0x01) {
                            data = "Generic Desktop Page";
                        }
                        else if (data0 == 0x07)
                        {
                            data = "Keyboard/Keypad Page";
                        }
                        else if (data0 == 0x08)
                        {
                            data = "LED Page";
                        }
                        else if (data0 == 0x09)
                        {
                            data = "Button Page";
                        }
                        else if (data0 == 0x0C)
                        {
                            data = "Consumer Page";
                        }


                    }
                    else if (tag == 1)
                    {
                        stag = "Logical Minimum";
                    }
                    else if (tag == 2)
                    {
                        stag = "Logical Maximum";
                    }
                    else if (tag == 3)
                    {
                        stag = "Physical Minimum";
                    }
                    else if (tag == 4)
                    {
                        stag = "Physical Maximum";
                    }
                    else if (tag == 5)
                    {
                        stag = "Unit Exponent";
                    }
                    else if (tag == 6)
                    {
                        stag = "Unit";
                    }
                    else if (tag == 7)
                    {
                        stag = "Report Size";
                        data = "localUserPage:" + Util.getHex2(localUserPage) + " globalUserPage:" + Util.getHex2(globalUserPage);
                    }
                    else if (tag == 8)
                    {
                        stag = "Report ID";
                    }
                    else if (tag == 9)
                    {
                        stag = "Report Count";
                    }
                    else if (tag == 10)
                    {
                        stag = "Push";
                    }
                    else if (tag == 11)
                    {
                        stag = "Pop";
                    }
                    else
                    {
                        stag = "?";
                    }
                }
                else if (type == 2)
                {
                    stype = "Local";
                    if (tag == 0)
                    {
                        stag = "Usage";
                        if (globalUserPage == 0x01) //Generic Desktop Page
                        {
                            localUserPage = data0;
                            if (data0 == 0x01)
                            { 
                                data = "Pointer";
                            }
                            if (data0 == 0x02)
                            { 
                                data = "Mouse";
                            }
                            if (data0 == 0x06)
                            {
                                data = "Keyboard";
                            }
                            if (data0 == 0x30) { 
                                data = "X";
                            }
                            if (data0 == 0x31) {
                                data = "Y";
                            }
                            if (data0 == 0x38)
                            {
                                data = "Wheel";
                            }
                            if (data0 == 0x80)
                            {
                                data = "System Control";
                            }
                        }
                        else if (globalUserPage == 0x0C)//Consumer Page
                        {
                            localUserPage = data0;
                            if (data0 == 0x01)
                            {
                                data = "Consumer Control";
                            }
                        }
                    }
                    else if (tag == 1)
                    {
                        stag = "Usage Minimum";
                    }
                    else if (tag == 2)
                    {
                        stag = "Usage Maximum";
                    }
                    else if (tag == 3)
                    {
                        stag = "Designator Index";
                    }
                    else if (tag == 4)
                    {
                        stag = "Designator Minimum";
                    }
                    else if (tag == 5)
                    {
                        stag = "Designator Maximum";
                    }
                    else if (tag == 7)
                    {
                        stag = "String Index";
                    }
                    else if (tag == 8)
                    {
                        stag = "String Minimum";
                    }
                    else if (tag == 9)
                    {
                        stag = "String Maximum";
                    }
                    else if (tag == 10)
                    {
                        stag = "Delimiter";
                    }
                    else
                    {
                        stag = "?";
                    }
                }
                else if (type == 3)
                {
                    stype = "Reserved";
                }
                for (int i = 0; i < indent; i++)
                {
                    sb.Append("  ");
                }
                if (type == 0 && tag == 10)
                {
                    indent++;
                }
                if (data != "") {
                    data = "\"" + data + "\"";
                }
                sb.Append(stype + " " + stag + " " + data + " ");
                for (int i = 0; i < len; i++)
                {
                    sb.Append(arr[idx++] + " ");
                }
                sb.AppendLine();
            }
            return sb.ToString();
        }

        private void button11_Click(object sender, EventArgs e)
        {
            clearBuff();

            loadSym();

            sendCmd(HALT_DEBUG, 1);//halt_uart

            setmem(0x50000000, 0);//low speed

            uint baseAddr = 0x00000000;

            loadprog("out.bin");//, baseAddr = 0

            //      end else if (command == 8'h02) begin debug_reset_n<=data[0]; command_done<=1;

            //debug mode
            //sendCmd(SET_DEBUG_FLG, 1);
            sendCmd(SET_DEBUG_FLG, 0);

            sendCmd(DEBUG_RESET_N0);//debug_reset_n<=1'b0
            sendCmd(DEBUG_RESET_N1);

            if (checkBox11.Checked)
            {
                setmem(0x50000000, 1);//high speed
            }
            else
            {
                setmem(0x50000000, 0);//low speed
            }

            if (!checkBox1.Checked)
            {
                sendCmd(HALT_DEBUG, 0);//halt_uart<=1'b0
            }
        }
        public void loadprog(string filename)
        {
            FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
            int len = (int)fs.Length;
            int diff = len & 1023;
            len += 1024 - diff;
            byte[] data = new byte[len];
            fs.Read(data, 0, (int)fs.Length);
            fs.Close();

            for (uint baseAddr = 0; baseAddr < len; baseAddr += 1024)//data.Length
            {
                memBatchWrite1024(data, baseAddr, baseAddr);
                FlushCache(baseAddr);
                FlushCache(baseAddr + 1024);

                this.Text = baseAddr.ToString();
                Application.DoEvents();
            }
            byte[] buff = new byte[1024];
            int err = 0;
            for (uint baseAddr = 0; baseAddr < len; baseAddr += 1024)//data.Length
            {
                memBatchRead1024(buff, baseAddr);
                for (uint i = 0; i < 1024; i += 4)
                {
                    bool fix = false;
                    if (buff[i + 0] != data[i + 0 + baseAddr]) { err++; fix = true; }
                    if (buff[i + 1] != data[i + 1 + baseAddr]) { err++; fix = true; }
                    if (buff[i + 2] != data[i + 2 + baseAddr]) { err++; fix = true; }
                    if (buff[i + 3] != data[i + 3 + baseAddr]) { err++; fix = true; }
                    if (fix)
                    {
                        uint val = 0;
                        val |= (uint)data[i + 0 + baseAddr] << 0;
                        val |= (uint)data[i + 1 + baseAddr] << 8;
                        val |= (uint)data[i + 2 + baseAddr] << 16;
                        val |= (uint)data[i + 3 + baseAddr] << 24;
                        setmem(i + baseAddr, val);
                        FlushCache(i + baseAddr);
                        Console.WriteLine("fix" + Util.getHex8(i + baseAddr) + ":" + Util.getHex8(val));
                        baseAddr -= 1024; break;
                    }
                }
                if (err > 1000) break;
                this.Text = baseAddr.ToString();
                Application.DoEvents();
            }

            setmem((uint)(CACHE_CTL), 0x40000000);
            setmem(CACHE_CTL, 0);

            //reset reg
            //for (int i = 0; i < 2048; i++)
            //{
            //    buff[i] = 0;
            //}
            //send(buff);

            textBox4.Text = "err:" + err.ToString();
        }

        uint VGA = 0x4C200000;
        uint VGA_MODE = 0x0000;
        uint VGA_BLOCK = 0x0800;
        uint VGA_BASE = 0x1000;
        uint VGA_CURSOR_DATA = 0x1800;
        uint VGA_CURSOR_X = 0x2000;
        uint VGA_CURSOR_Y = 0x2800;
        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            sendCmd(SET_DEBUG_VGA_BASE_ADDR,0x80000000 | (uint)(-trackBar1.Value));
            this.Text = "" + ((uint)(-trackBar1.Value));
        }
        void trackBar1_MouseUp(object sender, MouseEventArgs e)
        {
            sendCmd(SET_DEBUG_VGA_BASE_ADDR, 0);
        }

        void trackBar1_MouseDown(object sender, MouseEventArgs e)
        {
            sendCmd(SET_DEBUG_VGA_BASE_ADDR, 0x80000000 | (uint)(-trackBar1.Value));
        }


        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
        }

        private void checkBox3_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox3.Checked)
            {
                setmem(0x4C002000, 1);
            }
            else
            {
                setmem(0x4C002000, 0);
            }

        }


        private void checkBox4_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void button16_Click_1(object sender, EventArgs e)
        {
            Form3 form3 = new Form3();
            form3.mainForm = this;
            form3.Show();
            stop = true;
        }

        private void checkBox8_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox8.Checked)
            {
                sendCmd(NOCACHE1);//nocache
            }
            else
            {
                sendCmd(NOCACHE0);//nocache
            }
        }

        public uint getReg(uint addr)
        {
            sendCmd(SET_DEBUG_ADDRESS, addr);
            uint val = sendCmdRet(REG_READ);
            return val;
        }
        public void getReg(uint addr, byte[] buff, uint index)
        {
            sendCmd(SET_DEBUG_ADDRESS, addr);
            sendCmd(SET_DEBUG_ADDRESS, addr);
            uint val = sendCmdRet(REG_READ);
            buff[index + 0] = (byte)(val >> 0);
            buff[index + 1] = (byte)(val >> 8);
            buff[index + 2] = (byte)(val >> 16);
            buff[index + 3] = (byte)(val >> 24);
        }
        //public void setReg(uint addr, uint val)
        //{
        //    sendCmd(SET_DEBUG_ADDRESS, addr);
        //    sendCmd(SET_DEBUG_WRITEDATA, val);
        //    uint ret = sendCmdRet(REG_WRITE);
        //}

        //public void setReg(uint addr, byte[] buff, uint index)
        //{
        //    sendCmd(SET_DEBUG_ADDRESS, addr);
        //    sendCmd(SET_DEBUG_ADDRESS, addr);
        //    uint val = 0;
        //    val |= (uint)buff[index + 0] << 0;
        //    val |= (uint)buff[index + 1] << 8;
        //    val |= (uint)buff[index + 2] << 16;
        //    val |= (uint)buff[index + 3] << 24;
        //    sendCmd(SET_DEBUG_WRITEDATA, val);
        //    uint ret = sendCmdRet(REG_WRITE);
        //}

        //uint[] regArray = new uint[32];
        private uint getReg(int index, StringBuilder sb)
        {
            //uint val = regArray[index];
            sendCmd(SET_DEBUG_ADDRESS, (uint)index);
            uint val = sendCmdRet(REG_READ);
            if (sb != null)
            {
                sb.Append(Util.getHex8(val));
            }
            return val;
        }

        private void getRegArray()
        {
            //sendCmd(SET_TRANSFER_BASE_ADDR, 0);
            //byte[] data = new byte[2048];
            //receive(data);
            //
            //for (uint i = 0; i < 32; i++)
            //{
            //    uint val = 0;
            //    val |= data[i * 4];
            //    val |= (uint)(data[i * 4 + 1] << 8);
            //    val |= (uint)(data[i * 4 + 2] << 16);
            //    val |= (uint)(data[i * 4 + 3] << 24);
            //    regArray[i] = val;
            //}
        }


        private void button17_Click(object sender, EventArgs e)
        {
            {
                Random r = new Random();
                StringBuilder sb = new StringBuilder();
                StringBuilder sb1 = new StringBuilder();
                StringBuilder sb2 = new StringBuilder();

                int err1 = 0;
                int err2 = 0;
                int baseErr = 0;
                //send
                {
                    byte[] alldata = new byte[1024];
                    r.NextBytes(alldata);
                    //for (int i = 0; i < alldata.Length; i+=2)
                    //{
                    //    if ((i & 2) == 0)
                    //    {
                    //        alldata[i + 0] = 0xFF;//cy_B
                    //        alldata[i + 1] = 0xFF;//err 0x20, FF->DF cy_D
                    //    }
                    //    else {
                    //        alldata[i + 0] = 0x00;
                    //        alldata[i + 1] = 0x00;//err 0x20, FF->DF
                    //    }
                    //}

                    //write

                    memBatchWrite1024(alldata, 0, 0);

                    for (uint i = 0; i < 1024; i += 4)
                    {
                        uint data = getmem(i, null);
                        byte d0 = (byte)(data >> 0);
                        byte d1 = (byte)(data >> 8);
                        byte d2 = (byte)(data >> 16);
                        byte d3 = (byte)(data >> 24);
                        string strerr0 = " ";
                        string strerr1 = " ";
                        string strerr2 = " ";
                        string strerr3 = " ";
                        if (d0 != alldata[i + 0]) { err1++; strerr0 = "*"; }
                        if (d1 != alldata[i + 1]) { err1++; strerr1 = "*"; }
                        if (d2 != alldata[i + 2]) { err1++; strerr2 = "*"; }
                        if (d3 != alldata[i + 3]) { err1++; strerr3 = "*"; }
                        sb1.Append(Util.getHex2(alldata[i + 0]) + strerr0);
                        sb1.Append(Util.getHex2(alldata[i + 1]) + strerr1);
                        sb1.Append(Util.getHex2(alldata[i + 2]) + strerr2);
                        sb1.Append(Util.getHex2(alldata[i + 3]) + strerr3);
                        sb2.Append(Util.getHex2(d0) + strerr0);
                        sb2.Append(Util.getHex2(d1) + strerr1);
                        sb2.Append(Util.getHex2(d2) + strerr2);
                        sb2.Append(Util.getHex2(d3) + strerr3);
                        if (((i + 4) & 63) == 0)
                        {
                            sb.Append(sb1 + "\r\n" + sb2 + "\r\n");
                            sb1.Clear();
                            sb2.Clear();
                        }
                    }
                }
                sb.AppendLine();
                {
                    byte[] alldata = new byte[1024];
                    r.NextBytes(alldata);
                    //for (int i = 0; i < alldata.Length; i+=2)
                    //{
                    //    alldata[i+0] = 0xFF;
                    //    alldata[i+1] = 0xFF;//00->20
                    //}

                    for (uint i = 0; i < 1024; i += 4)
                    {
                        uint data = 0;
                        data |= (uint)alldata[i + 0] << 0;
                        data |= (uint)alldata[i + 1] << 8;
                        data |= (uint)alldata[i + 2] << 16;
                        data |= (uint)alldata[i + 3] << 24;
                        setmem(i, data);
                    }
                    byte[] data_in = new byte[1024];
                    memBatchRead1024(data_in, 0);

                    for (uint i = 0; i < 1024; i++)
                    {
                        if (data_in[i] != alldata[i])
                        {
                            err2++;
                            sb1.Append(Util.getHex2(alldata[i]) + "*");
                            sb2.Append(Util.getHex2(data_in[i]) + "*");
                        }
                        else {
                            sb1.Append(Util.getHex2(alldata[i]) + " ");
                            sb2.Append(Util.getHex2(data_in[i]) + " ");
                        }
                        if (((i+1) & 63) == 0)
                        {
                            sb.Append(sb1 + "\r\n" + sb2 + "\r\n");
                            sb1.Clear();
                            sb2.Clear();
                        }
                    }

                    for (uint i = 0; i < 1024; i += 4)
                    {
                        uint data = getmem(i, null);
                        byte d0 = (byte)(data >> 0);
                        byte d1 = (byte)(data >> 8);
                        byte d2 = (byte)(data >> 16);
                        byte d3 = (byte)(data >> 24);
                        if (d0 != alldata[i + 0]) { baseErr++;  }
                        if (d1 != alldata[i + 1]) { baseErr++;  }
                        if (d2 != alldata[i + 2]) { baseErr++;  }
                        if (d3 != alldata[i + 3]) { baseErr++;  }
                    }

                }

                this.textBox4.Text = "PC2FPGAerr1:" + err1 + "  FPGA2PCerr2:" + err2 + "  baseBandErr:" + baseErr + "\r\n" + sb.ToString() + "\r\n";
            }
            return;
            //{
            //    //sendCmd(SET_TRANSFER_BASE_ADDR, 0);
            //
            //    byte[] data_buff = new byte[1024];
            //
            //    Random r = new Random();
            //    r.NextBytes(data_buff);
            //
            //
            //    send1024(data_buff);
            //
            //    //transfer r
            //    //8'h22 : begin transferBaseAddr <= ch341a_data; command_ack<=1; end
            //
            //    byte[] data = new byte[1024];
            //    receive1024(data);
            //
            //    StringBuilder sb = new StringBuilder();
            //    int err1 = 0;
            //    int err2 = 0;
            //    for (uint i = 0; i < 256; i++)
            //    {
            //        if ((i & 3) == 0)
            //        {
            //            sb.Append("\r\n" + Util.getHex4((int)i) + ":");
            //        }
            //
            //        uint val = 0;
            //        val |= data[i * 4];
            //        val |= (uint)(data[i * 4 + 1] << 8);
            //        val |= (uint)(data[i * 4 + 2] << 16);
            //        val |= (uint)(data[i * 4 + 3] << 24);
            //
            //        sb.Append(Util.getHex8(val)); sb.Append(" ");
            //
            //        uint val2 = 0;
            //        val2 |= data_buff[i * 4];
            //        val2 |= (uint)(data_buff[i * 4 + 1] << 8);
            //        val2 |= (uint)(data_buff[i * 4 + 2] << 16);
            //        val2 |= (uint)(data_buff[i * 4 + 3] << 24);
            //        if (val != val2)
            //        {
            //            err1++;
            //        }
            //
            //    }
            //
            //    for (uint i = 0; i < 256; i++)
            //    {
            //        if ((i & 3) == 0)
            //        {
            //            sb.Append("\r\n" + Util.getHex4((int)i) + ":");
            //        }
            //        sendCmd(SET_DEBUG_ADDRESS, i * 4);
            //
            //        uint val = sendCmdRet(REG_READ);
            //        sb.Append(Util.getHex8(val));
            //        sb.Append(" ");
            //        uint val2 = 0;
            //        val2 |= data_buff[i * 4];
            //        val2 |= (uint)(data_buff[i * 4 + 1] << 8);
            //        val2 |= (uint)(data_buff[i * 4 + 2] << 16);
            //        val2 |= (uint)(data_buff[i * 4 + 3] << 24);
            //        if (val != val2)
            //        {
            //            err2++;
            //        }
            //
            //    }
            //    this.textBox4.Text = "batcherr:" + err1 + ", single err:" + err2 + "," + sb.ToString();
            //}
        }

        public void memBatchWrite1024(byte[] alldata, uint index, uint baseAddr)//1k
        {
            sendCmd(SET_DEBUG_RW_CMD, 1);//stw
            byte[] data_out = new byte[1024];
            for (int i = 0; i < 1024; i++)
            {
                data_out[i] = alldata[i + index];
            }

            //Stopwatch sw = new Stopwatch();
            //sw.Start();
            send1024(data_out);
            //long v1 = sw.ElapsedTicks;
            //sendCmd(SET_DEBUG_ADDRESS, baseAddr);
            uint ret = sendCmdRet(MEM_TRANS_WRITE, baseAddr);//1024 + 
            //long v2 = sw.ElapsedTicks;
            //Console.WriteLine("w"+v1);
            //Console.WriteLine("w" + v2);
            if (ret != 123)
            {
                throw new Exception();
            }
        }
        public void memBatchRead1024(byte[] data, uint baseAddr)//1k
        {
            sendCmd(SET_DEBUG_RW_CMD, 0);//ldw
            //sendCmd(SET_DEBUG_ADDRESS, baseAddr);
            //Stopwatch sw = new Stopwatch();
            //sw.Start();
            uint ret = sendCmdRet(MEM_TRANS_READ, baseAddr);//1024 + 
            //long v1 = sw.ElapsedTicks;
            if (ret != 123)
            {
                throw new Exception();
            }

            receive1024(data);
            //long v2 = sw.ElapsedTicks;
            //Console.WriteLine("r"+v1);
            //Console.WriteLine("r"+v2);
        }

        const int size = 1*1024;// k
        byte[] alldata = new byte[size * 1024];
        void loadalldata()
        {
            if (File.Exists("alldata.hex"))
            {
                FileStream fs = new FileStream("alldata.hex", FileMode.Open, FileAccess.Read);
                fs.Read(alldata, 0, size * 1024);
                fs.Close();
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {

            int totalretry = 0;
            byte[] data_in = new byte[1024];

            int a = 0;

            Random r = new Random();
            r.NextBytes(alldata);

            FileStream fs = new FileStream("alldata.hex", FileMode.Create, FileAccess.Write);
            fs.Write(alldata, 0, size * 1024);
            fs.Close();

            //write
            for (uint baseAddr = 0; baseAddr < size * 1024; baseAddr += 1024)
            {
                int retry;
                for (retry = 0; retry < 5; retry++)
                {
                    memBatchWrite1024(alldata, baseAddr, baseAddr);
                    memBatchRead1024(data_in, baseAddr);
                    bool iserr = false;
                    for (int i = 0; i < 1024; i++)
                    {
                        if (data_in[i] != alldata[i + baseAddr])
                        {
                            iserr = true;
                        }
                    }
                    if (!iserr)
                    {
                        break;
                    }
                }
                if (retry == 5)
                {
                    throw new Exception();
                }
                totalretry += retry;
                this.Text = "" + baseAddr / 1024;
            }

            this.textBox4.Text = "retry:" + totalretry;// +sb.ToString() + "\r\n" + sb2.ToString();
        }

        private void button13_Click(object sender, EventArgs e)
        {

            int b = 0;
            int err = 0;
            int totalretry = 0;
            byte[] data_in = new byte[1024];
            StringBuilder sb = new StringBuilder();
            for (uint baseAddr = 0; baseAddr < size * 1024; baseAddr += 1024)
            {
                int retry;
                for (retry = 0; retry < 4; retry++)
                {
                    memBatchRead1024(data_in, baseAddr);
                    bool iserr = false;
                    for (int i = 0; i < 1024; i++)
                    {
                        if (data_in[i] != alldata[i + baseAddr])
                        {
                            iserr = true;
                        }
                    }
                    if (!iserr)
                    {
                        break;
                    }
                }
                if (retry == 4)
                {
                    sb.AppendLine(Util.getHex8(baseAddr));
                    err++;
                }
                if (err > 32)
                {
                    break;
                }
                totalretry += retry;
                this.Text = "" + baseAddr / 1024;
            }
            this.textBox4.Text = "err:" + err + "   retry:" + totalretry+ "\r\n"+sb.ToString();// +sb.ToString() + "\r\n" + sb2.ToString();
        }


        private void button8_Click_1(object sender, EventArgs e)
        {
            Form4 form = new Form4();
            form.usevga = checkBox10.Checked;
            form.baseAddr = uint.Parse(textBox7.Text) / 2;// Convert.ToUInt32(this.textBox1.Text, 16);
            form.mainForm = this;
            form.ShowDialog();
        }

        private void button12_Click(object sender, EventArgs e)
        {
            BaseTest form = new BaseTest();
            form.mainForm = this;
            form.Show();
        }

        private void checkBox11_CheckedChanged(object sender, EventArgs e)
        {
            //video
            checkBox1.Checked = true;
            if (checkBox11.Checked)
            {
                setmem(0x50000000, 1);
            }
            else
            {
                setmem(0x50000000, 0);
            }
        }

/*
        static EventWaitHandle handleA = new AutoResetEvent(false);
        static EventWaitHandle handleB = new AutoResetEvent(false);
        static byte[] data_in;
        static int line;
        static Bitmap bmp;
        static Form4 form;
        static void proc()
        {
            bmp = new Bitmap(1024, 768);
            form = new Form4();
            form.img = bmp;
            //form.Show();
            handleB.Reset();
            handleB.Set();
            for (uint index = 0; index < 1024 * 768 * 2; index += 2048)
            {
                handleA.WaitOne();
                for (int i = 0; i < 2048; i += 2)
                {
                    int b = data_in[i] & 0x1F;
                    int g = ((data_in[i] >> 5) | (data_in[i + 1] << 3)) & 0x3F;
                    int r = data_in[i + 1] >> 3;
                    bmp.SetPixel(i >> 1, line, Color.FromArgb(r << 3, g << 2, b << 3));
                }
                line++;
                form.Refresh();
            }
            bmp.Save(DateTime.Now.ToString("yyyy-MM-dd HH_mm_ss")+".jpg");
            //Application.Run(form);
        }



        private void button8_Click_1(object sender, EventArgs e)
        {
            uint baseAddr = uint.Parse(textBox7.Text) / 2;// Convert.ToUInt32(this.textBox1.Text, 16);

            //checkBox1.Checked = true;
            //sendCmd(HALT_DEBUG1);
            //
            //byte[] save_regs = new byte[2048];
            //receive(save_regs);
            //
            ////uint baseAddr = 2048*1024;// Convert.ToUInt32(this.textBox1.Text, 16);
            line = 0;
            data_in = new byte[2048];
            Thread drawthread = new Thread(proc);
            drawthread.Start();
            handleA.Reset();
            handleB.WaitOne();
            //for (uint index = 0; index < 1024 * 768 * 2; index += 2048)
            //{
            //    memBatchRead(data_in, index + baseAddr);
            //    handleA.Set();
            //    this.Text = "" + index / 1024;
            //}
            //
            //send(save_regs);


            sendCmd(VGA_CONTROL_BY_DEBUGGER, 1);
            for (uint index = 0; index < 768; index++)
            {
                //memBatchRead(data_in, index + baseAddr);
                sendCmd(VGA_DEBUGGER_READ_LINE_ADDR, index + baseAddr);//0~16k, 14bit

                uint ret = sendCmdRet(VGA_DEBUGGER_READ_LINE_REQ);
                receive(data_in);
                handleA.Set();
                this.Text = "" + index;
            }


            sendCmd(VGA_CONTROL_BY_DEBUGGER, 0);

        }
*/

    }
}
